'use strict';

const crypto = require('crypto');

/**
 * 辅助函数
 * **/
module.exports = {
  /**
   * 创建 model 对象
   * @param {String} m model title
   * @param {Object} o model data
   *
   * @return {Object} Model
   * **/
  model(m, o) {
    const mongoose = this.app.mongoose;

    const schema = new mongoose.Schema(Object.assign({
      language: {
        type: String,
        displayName: '语言类型',
        default: 'zh'
      },
    }, o), {
        timestamps: {
          createdAt: 'create_time',
          updatedAt: 'update_time',
        },
      });

    return mongoose.model(m, schema);
  },


  PopulateResult(ctx_populate, modelName, result) {
    let path = []   //缓存填充路线
    let pop = ctx_populate
    let key = modelName
    function a(pop, key) {
      let obj = pop[key]
      let ret;
      path.push(key)
      if (obj != undefined) {
        for (let i in obj) {
          let key = obj[i]
          if (!path.includes(key)) {
            obj[i] = a(pop, key)
            delete path[path.indexOf(key)]
          } else {
            //调试时 注释掉此处 输出 ret 有助于理解
            delete obj[i]
          }
        }
        ret = obj
      } else {
        ret = key
      }
      return ret
    }
    let maps = []
    let map = []
    function c(aa) {
      for (let i in aa) {
        //console.log(aa[i]);
        if (map.includes(i)) {
          map.splice(map.indexOf(i), map.length - map.indexOf(i))
        }
        map.push(i)
        //console.log(aa[i] instanceof Object);

        if (aa[i] instanceof Object) {
          c(aa[i])
        } else {
          maps.push(JSON.stringify(map))
          map.pop()
        }
      }
      map = []
    }
    c(a(pop, key))  //产生maps
    //return maps

    let config = {}
    for (let map of maps) {
      let mapArr = JSON.parse(map)
      //console.log(mapArr instanceof Array);
      //console.log(mapArr);
      for (let i = mapArr.length - 1; i >= 0; i--) {
        if (i == mapArr.length - 1) {
          config = { path: mapArr[i] }
        }
        if (i < mapArr.length - 1) {
          config = {
            path: mapArr[i],
            populate: config
          }

        }
      }
      //console.log(config);
      result = result.populate(config);
      config = {}
    }
  
    return result
  },
  /**
   * md5
   * @param {String} str 加密字符
   *
   * @return {String} md5 加密字符
   **/
  md5(str) {
    const md5sum = crypto.createHash('md5');
    md5sum.update(str);
    str = md5sum.digest('hex');
    return str;
  },

  /**
   * 计算结束日期是参数起始日期后的第几周
   * @param {String} date1 起始日期
   * @param {String} date2 结束日期
   *
   * @return {Number} 跟起始日期相差的周数，起始日期为第一周
   * **/
  getYearWeek(date1, date2) {
    function week(date) {
      date = new Date(date);
      const date2 = new Date(date.getFullYear(), 0, 1);

      let day1 = date.getDay();
      if (day1 === 0) day1 = 7;

      let day2 = date2.getDay();
      if (day2 === 0) day2 = 7;

      const d = Math.round((date.getTime() - date2.getTime() + (day2 - day1) * (24 * 60 * 60 * 1000)) / 86400000);

      return Math.ceil(d / 7) + 1;
    }

    return week(date2) - week(date1) + 1;
  },

  /**
   * 计算结束月份是参数月份后的第几月
   * @param {String} date1 起始月份
   * @param {String} date2 结束月份
   *
   * @return {Number} 跟起始月份相差的月数，起始日期为第一月
   * **/
  getYearMonth(date1, date2) {
    function month(date) {
      date = new Date(date);

      return date.getMonth();
    }

    return month(date2) - month(date1) + 1;
  },

  /**
   * 根据第几周算出实际日期
   * @param {Number} week 第几周
   *
   * @return {Object} 起止日期
   * **/
  getRealWeek(week) {
    const time = new Date(new Date().getFullYear().toString()).getTime();
    const start = time + 1000 * 60 * 60 * 24 * 7 * (week - 1);
    const end = time + 1000 * 60 * 60 * 24 * 7 * week;

    return {
      start: new Date(start),
      end: new Date(end),
    };
  },

  /**
   * 获取年月日
   * @param {Date} date 时间
   *
   * @return {String} 年月日
   * **/
  getYearMonthDay(date) {
    date = new Date(date);

    return `${date.getFullYear()}-${date.getMonth() + 1}-${date.getDate()}`;
  },

  /**
   * 当前日期字符串
   *
   * @return {String}
   * **/
  getDateString() {
    const date = new Date();

    return date.getFullYear() +
      (parseInt(date.getMonth()) < 9 ? '0' + (parseInt(date.getMonth()) + 1) : parseInt(date.getMonth()) + 1) +
      (parseInt(date.getDate()) < 10 ? '0' + date.getDate() : date.getDate()) + '-';
  },
};
